package com.andatsoft.laisim.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import com.andatsoft.laisim.theme.ThemeManager;

public class CircularProgressBar extends View {
	private int mProgress = 0;// min 0; max 180
	private int mMax = 100;
	private float mAngle;
	private boolean mIsTouchOverValue;
	// Rectangles
	private Matrix mMatrix;

	// Attributes
	private int layout_width = 200;// the width of the view
	private int layout_height = 200;// the height of the view

	private Paint mImagePainter;

	// Bitmap show the progress bar
	private Bitmap mImage;
	private Bitmap mImageThumb;

	public interface IProgressChanged {
		public void onProgressChanged(int newProgress);
	}

	private IProgressChanged mIProgressChanged;

	public CircularProgressBar(Context c) {
		super(c);
		mMatrix = new Matrix();
	}

	public CircularProgressBar(Context context, AttributeSet attrs) {
		super(context, attrs);
		mMatrix = new Matrix();

	}

	private void setupPainters() {

		mImagePainter = new Paint();
		mImagePainter.setStyle(Style.FILL);
		mImagePainter.setAntiAlias(true);
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);

		layout_width = w > h ? h : w;
		layout_height = layout_width;

		setupPainters();
		// setupGradient();
		setImage(ThemeManager.getSelectedSkin()
				.getProgressCircularBackgroundNormal());
		setThumb(ThemeManager.getSelectedSkin().getProgressCircularThumb());
		invalidate();
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		// draw background
		canvas.drawBitmap(mImage, 0, 0, mImagePainter);
		mMatrix.setRotate(mAngle, layout_width / 2, layout_height / 2);
		// draw the image
		canvas.drawBitmap(mImageThumb, mMatrix, null);

	}

	/**
	 * @param progress
	 *            : The progress of task. From 0 to 100
	 */
	public void setProgress(int progress) {
		// int value = progress * 180 / 100;
		if (progress < 0)
			this.mProgress = 0;
		if (progress > mMax)
			this.mProgress = mMax;
		this.mProgress = progress;
		calculateProgressToAngle();
		invalidate();
	}

	public int getProgress() {
		return mProgress;
	}

	public void setMax(int max) {
		this.mMax = max;
	}

	public int getMax() {
		return mMax;
	}

	private void setImage(Drawable drawable) {
		mImage = ((BitmapDrawable) drawable).getBitmap();
		if (layout_width <= 0)
			layout_width = 200;
		if (layout_height <= 0)
			layout_height = 200;
		mImage = Bitmap.createScaledBitmap(mImage, layout_width, layout_height,
				true);
		invalidate();
	}

	private void setThumb(Drawable drawable) {
		mImageThumb = ((BitmapDrawable) drawable).getBitmap();
		mImageThumb = Bitmap.createScaledBitmap(mImageThumb, layout_width,
				layout_height, true);
		invalidate();
	}

	private void calculatePointToAngle(MotionEvent event) {
		float x = event.getX() - layout_width / 2;
		float y = layout_height / 2 - event.getY();
		// goc tren Ox
		if (event.getY() < layout_height / 2) {
			mAngle = (float) Math.toDegrees(Math.atan(x / y));
		} else {
			if (event.getX() < layout_width / 2) {
				mAngle = -(90 + (float) Math.toDegrees(Math.atan(y / x)));
			} else {
				mAngle = 90 - (float) Math.toDegrees(Math.atan(y / x));
			}
		}
		mIsTouchOverValue = false;
		// mAngle = mAngle % 120;
		if (mAngle < -120) {
			if (mAngle < -150) {
				mIsTouchOverValue = true;
			}
			mAngle = -120;
		}
		if (mAngle > 120) {
			if (mAngle > 150) {
				mIsTouchOverValue = true;
			}
			mAngle = 120;
		}
	}

	private void calculateAngleToProgress() {
		if (mAngle < 0) {
			mProgress = (int) (mMax - (mMax / 2 + -mAngle * mMax / 240));
		} else if (mAngle > 0) {
			mProgress = (int) (mMax / 2 + mAngle * mMax / 240);
		} else {
			mProgress = 50;
		}
		Log.e("Progress", mProgress + "");
	}

	private void calculateProgressToAngle() {
		if (mProgress < mMax / 2) {
			mAngle = -(120 - (mProgress * 120 / mMax));
		} else if (mProgress > mMax / 2) {
			mAngle = mProgress * 120 / mMax;
		} else {
			mAngle = 0;
		}
		Log.e("Progress", mProgress + "");
	}

	public void setOnProgressChanged(IProgressChanged event) {
		this.mIProgressChanged = event;
	}

	private boolean isTouchOutSideCircle(MotionEvent event) {
		float x0 = layout_width / 2;
		float y0 = layout_height / 2;
		float x = event.getX();
		float y = event.getY();
		double dis = Math.sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0));
		if (dis > layout_width / 2)
			return true;
		return false;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			if (isTouchOutSideCircle(event) || mIsTouchOverValue) {
				setImage(ThemeManager.getSelectedSkin()
						.getProgressCircularBackgroundNormal());
			} else {
				calculatePointToAngle(event);
				calculateAngleToProgress();
				if (mIProgressChanged != null)
					mIProgressChanged.onProgressChanged(mProgress);
				setImage(ThemeManager.getSelectedSkin()
						.getProgressCircularBackgroundPressed());
			}
			invalidate();
			return true;
		case MotionEvent.ACTION_MOVE:
			if (isTouchOutSideCircle(event) || mIsTouchOverValue) {
				setImage(ThemeManager.getSelectedSkin()
						.getProgressCircularBackgroundNormal());
			} else {
				calculatePointToAngle(event);
				calculateAngleToProgress();
				if (mIProgressChanged != null)
					mIProgressChanged.onProgressChanged(mProgress);
				setImage(ThemeManager.getSelectedSkin()
						.getProgressCircularBackgroundPressed());
			}
			invalidate();
			return true;
		case MotionEvent.ACTION_UP:
			setImage(ThemeManager.getSelectedSkin()
					.getProgressCircularBackgroundNormal());
			mIsTouchOverValue = false;
			invalidate();
			return true;
		}
		return true;
	}
}
